package com.ease.actionscript.mapping.mapper;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.ease.actionscript.mapping.util.ActionScriptTypeConverter;

/**
 * 
 * @author nathanleewei
 * 
 */
public class ValueObjectEnumMapper extends AbstractValueObjectClassMapper {

	public boolean isCompliant() {
		return super.isCompliant();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void prepare() {
		super.prepare();

		this.addImportClassName(CLASS_ENUM);
		this.addImportClassName(CLASS_ENUMCONSTANTS);

		initEnumFieldValueImports((Class<Enum>) clazz, memberFields);
	}

	public final <T extends Enum<T>> void initEnumFieldValueImports(Class<T> enumClass, List<Field> memberFields) {

		if (null != enumClass.getEnumConstants()) {
			for (T enumConstant : enumClass.getEnumConstants()) {
				if (notEmpty(memberFields)) {
					for (Field field : memberFields) {
						if (field.getType().equals(Class.class)) {
							String classFieldValue = this.getEnumFieldValue(enumClass, field, enumConstant);
							addImportClassName(classFieldValue);
						}
					}
				}
			}
		}
	}

	// 根据java类对象的类型返回vo类型
	// TODO merge with AbstractActionScriptTypeMapper.getFieldValue()
	public String getEnumFieldValue(Class<?> clazz, Field field, Enum<?> enumClass) {

		String accesser = "get";
		if ("boolean".equals(field.getType().getName())) {
			accesser = "is";
		}

		Method method = null;
		try {
			// BeanDescriptor
			// PropertyDescriptor pd = new PropertyDescriptor("x",rp.getClass());
			// Method methodGetx = pd.getReadMethod();
			// Object retvalx = methodGetx.invoke(rp);

			method = clazz.getMethod(accesser + StringUtils.capitalize(field.getName()), new Class<?>[0]);
		} catch (SecurityException e1) {
			e1.printStackTrace();
		} catch (NoSuchMethodException e1) {
			e1.printStackTrace();
		}
		if (null != method) {

			try {
				Object returnValue = method.invoke(enumClass, (Object[]) null);
				if (null == returnValue) {
					return "null";
				}

				if (field.getType().isEnum()) {
					return field.getType().getName() + "." + String.valueOf(returnValue);
				}

				if (field.getType().equals(Class.class)) {
					return ((Class<?>) returnValue).getName();
				}

				if (field.getType().isArray()) {

					Class<?> type = field.getType();
					String typeName = type.getName();

					if (typeName.startsWith(ActionScriptTypeConverter.NON_PRIMITIVE_ARRAY_PREFIX) && typeName.endsWith(";")) {
						String elementName = typeName.substring(ActionScriptTypeConverter.NON_PRIMITIVE_ARRAY_PREFIX.length(), typeName.length() - 1);
						if ("java.lang.String".equals(elementName)) {
							String[] values = (String[]) method.invoke(enumClass, (Object[]) null);
							// String[] values = (String[]) field.get(null);
							// new Array("one", "two", "three");
							return "new Array(\"" + StringUtils.join(values, "\", \"") + "\")";
						}
					}
				}

				if (String.class.equals(field.getType())) {
					return "\"" + String.valueOf(returnValue) + "\"";
				}
				return String.valueOf(returnValue);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

}